package com.work.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.work.entity.Academy;
import com.work.entity.Major;
import com.work.entity.StuClass;
import com.work.entity.Student;
import com.work.mapper.StudentMapper;
import com.work.service.IAcademyService;
import com.work.service.IMajorService;
import com.work.service.IStuClassService;
import com.work.service.IStudentService;
import com.work.vo.ExcelVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {

    @Autowired
    private IAcademyService academyService;

    @Autowired
    private IMajorService majorService;

    @Autowired
    private IStuClassService stuClassService;

    private static ExecutorService executorService = new ThreadPoolExecutor(10, 10,
            2000L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(10));

    /**
     * 由于线程不安全，需要在这里开启悲观锁
     */
    public synchronized void fun(CountDownLatch countDownLatch, List<ExcelVo> collect, List<ExcelVo> excelVoList){
        excelVoList.addAll(collect);
        countDownLatch.countDown();
    }

    @Override
    public List data(){

        //1.查询出所有的学生并封装
        List<Student> studentList = query().list();
        int size = studentList.size();
        List<ExcelVo> excelVoList = new ArrayList<>(size);
        CountDownLatch countDownLatch = new CountDownLatch((size / 500) + (size % 500 == 0 ? 0 : 1));

        // 由于表格可能会删除或增加数据，因此要对截取的数量进行限制
        int num=size - 5000;
        //1.1 使用线程加快读取

        for (int i = 0; i < size;i+=500){
            List<Student> list= null;
            if ((i+500)>size){
                list = studentList.subList(i, size);
            }else {
                list = studentList.subList(i, i + 500);
            }
            List<Student> finalList = list;
            executorService.submit(() -> {
                List<Student> students = finalList;
                List<ExcelVo> collect = students.stream().map(student -> {
                    ExcelVo excelVo = new ExcelVo();
                    BeanUtils.copyProperties(student, excelVo);

                    excelVo.setStuTime(student.getStuTime());
                    // TODO 加载图片 功能正常
                    // 注释起来是因为会影响导出的速度
//                    try {
//                        if (student.getStuPicture() != null) {
//                            excelVo.setStuPicture(new URL(student.getStuPicture()));
//                        }else{
//                            log.info("照片为空!");
//                        }
//                    } catch (MalformedURLException e) {
//                        e.printStackTrace();
//                    }
                    return excelVo;
                }).collect(Collectors.toList());
                fun(countDownLatch, collect, excelVoList);
            });

        }

        try {
            countDownLatch.await();
            //2.查询出所有的班级
            excelVoList.forEach(excelVo -> {
                StuClass stuClass = stuClassService.getOne(new QueryWrapper<StuClass>().eq("class_id",excelVo.getClassId()));
                if (stuClass!=null){
                    excelVo.setClassName(stuClass.getClassName());
                    excelVo.setMajorId(stuClass.getMajorId());
                }else{
                    excelVo.setClassName("暂无数据!");
                }
            });
            //3.查询出所有的专业
            excelVoList.stream().forEach(excelVo -> {
                Major major = majorService.getOne(new QueryWrapper<Major>().eq("major_id",excelVo.getMajorId()));
                if (major!=null){
                    excelVo.setMajorName(major.getMajorName());
                    excelVo.setAcademyId(major.getAcademyId());
                }else{
                    excelVo.setMajorName("暂无数据!");
                }

            });

            //4.查询出所有的书院
            excelVoList.stream().forEach(excelVo -> {
                Academy academy = academyService.getOne(new QueryWrapper<Academy>().eq("academy_id",excelVo.getAcademyId()));
                if (academy!=null){
                    excelVo.setAcademyName(academy.getAcademyName());
                }else{
                    excelVo.setAcademyName("暂无数据!");
                }

            });
            //6.返回
            return excelVoList;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Collections.emptyList();
    }

    /**
     * 导入文件 并解析
     * @param cachedDataList
     */
    @Override
    public void saveList(List<ExcelVo> cachedDataList) {
        //1. 取出目标元素
        List<Student> students=new ArrayList<>();
        //2. 封装
        cachedDataList.stream().forEach(vo ->{
            Student student=new Student();
            BeanUtils.copyProperties(vo,student);

            StuClass className = stuClassService.getOne(new QueryWrapper<StuClass>().eq("class_name", vo.getClassName()));
            student.setClassId(className.getClassId());

            students.add(student);
        });
        //3.保存
        saveBatch(students);
    }

}
